﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using Clarendon.AzureBilling.Library;

namespace Clarendon.AzureBilling.Library
{
    public class AzureBillingService : IBillingContract
    {
        /// <summary>
        /// static list of subscribers available to make WCF callbacks to - only one anticipated client but potentially many
        /// </summary>
        private static readonly List<IBillingContractCallback> Subscribers = new List<IBillingContractCallback>();
        /// <summary>
        /// A list of all hosted services managed by Windows Azure for the requested subscription
        /// </summary>
        private static List<HostedService> _services; 

        /// <summary>
        /// The method used to subscribe to the WCF callback
        /// </summary>
        public void ObserveServiceBillingContract()
        {
            var callback = OperationContext.Current.GetCallbackChannel<IBillingContractCallback>();
            if(!Subscribers.Contains(callback))
                Subscribers.Add(callback);
        }

        /// <summary>
        /// The method used to unsubscribe to the WCF callback
        /// </summary>
        public void UnobserveServiceBillingContract()
        {
            var callback = OperationContext.Current.GetCallbackChannel<IBillingContractCallback>();
            if (Subscribers.Contains(callback))
                Subscribers.Remove(callback);
        }

        /// <summary>
        /// Internal method used to callback the subscribers and pass the Hosted Services to 
        /// </summary>
        public void UpdateServiceRequestAndCallbackSubscribers(List<HostedService> services)
        {
            _services = services;
            Subscribers.ForEach((callback) =>
            {
                if (((ICommunicationObject)callback).State == CommunicationState.Opened)
                {
                    callback.ServiceDetails(_services);
                }
                else
                {
                    Subscribers.Remove(callback);
                }
            });
        }

        /// <summary>
        /// public interface method used to make an ad-hoc request to the service
        /// </summary>
        public List<HostedService> MakeAdHocServiceRequest()
        {
            _services = _services ?? new List<HostedService>();
            
            return _services;
        }
    }
}
